package domain.simplex;

import java.util.ArrayList;
import java.util.List;

/**
 * the slack form is composed of N: non-basic vars x_j B: basic vars x_i A:
 * coefficients matrix a_ij b_i: constants such that x_i = b_i - a_ij * x_j c_j:
 * coefficients of vars in objective funtion, e.g., z = v + c_j * x_j v: as
 * above
 * 
 * In a nutshell: z = v + SUM(j in NonbasicVars) c_j * x_j x_i = b_i - SUM(j in
 * NonbasicVars) a_ij * x_j for i in BasicVars
 * 
 * @author j55wu
 * 
 */
public class SimplexSlackForm {

	private List<Integer> nonbasicVars; // contains x_j
	private List<Integer> basicVars;// contains x_i, the number of inequations
	private double[][] aij;
	private double[] bi;
	private double[] cj;
	private double v;

	public int getNumberofI() {
		return this.bi.length;
	}

	public List<Integer> getNonbasicVars() {
		return nonbasicVars;
	}

	public Integer getNonbasicVars(int j) {
		return nonbasicVars.get(j);
	}

	public int numOfAllVars() {
		return this.basicVars.size() + this.nonbasicVars.size();
	}

	public void rmNonBasicVar(int i) {
		this.nonbasicVars.remove(new Integer(i));
	}

	public void rmBasicVar(int i) {
		this.basicVars.remove(new Integer(i));
	}

	public List<Integer> getBasicVars() {
		return basicVars;
	}

	public Integer getBasicVars(int i) {
		return basicVars.get(i);
	}

	public double[] getAijRow(int i) {
		return aij[i];
	}

	public double getAij(int i, int j) {
		// int ti = this.basicVars.get(i);
		// int tj = this.nonbasicVars.get(j);
		// return aij[ti][tj];
		return aij[i][j];
	}

	public void clearAijRow(int i) {
		double[] inner = aij[i];
		for (int j = 0; j < inner.length; j++) {
			aij[i][j] = 0;
		}
	}

	// clear var i's value in every row
	public void clearAijColumn(int i) {
		for (Integer var : this.basicVars) {
			this.setAij(var, i, 0);
		}
	}

	public void setAij(int i, int j, double value) {
		aij[i][j] = value;
		return;
	}

	public double[] getBi() {
		return bi;
	}

	public double getBi(int index) {
		return bi[index];
	}

	public void setBi(int i, double value) {
		bi[i] = value;
		return;
	}

	public double[] getCj() {
		return this.cj;
	}

	public double getCj(int i) {
		return cj[i];
	}

	public void setCj(int i, double v) {
		cj[i] = v;
		return;
	}

	public double getV() {
		return v;
	}

	public void setV(double v) {
		this.v = v;
		return;
	}

	public SimplexSlackForm(List<Integer> nonbasicVars,
			List<Integer> basicVars, double[][] aij, double[] bi, double[] cj,
			double v) {
		super();
		this.nonbasicVars = nonbasicVars;
		this.basicVars = basicVars;
		this.aij = aij;
		this.bi = bi;
		this.cj = cj;
		this.v = v;
	}

	// remove a var from NB, and add it to B
	public void addAsBasicVar(Integer item) {
		this.nonbasicVars.remove(item);
		this.basicVars.remove(item);// remove duplicate copy
		this.basicVars.add(item);
	}

	// remove a var from B, and add it to NB
	public void addAsNonBasicVar(Integer item) {
		this.basicVars.remove(item);
		this.nonbasicVars.remove(item);// remove duplicate copy
		this.nonbasicVars.add(item);
	}

	public static SimplexSlackForm deepcopySlackForm(SimplexSlackForm sf) {
		int aijSize = sf.aij.length;
		double[][] newAij = new double[aijSize][aijSize];
		System.arraycopy(sf.aij, 0, newAij, 0, aijSize);
		double[] newBi = new double[aijSize];
		System.arraycopy(sf.bi, 0, newBi, 0, aijSize);
		double[] newCj = new double[aijSize];
		System.arraycopy(sf.cj, 0, newCj, 0, aijSize);
		List<Integer> newNBVars = new ArrayList<Integer>(sf.nonbasicVars);
		List<Integer> newBVars = new ArrayList<Integer>(sf.basicVars);
		double newV = sf.v;
		return new SimplexSlackForm(newNBVars, newBVars, newAij, newBi, newCj,
				newV);
	}

}
